package com.example.roleplay.service.impl;

import com.example.roleplay.config.RoleplayProperties;
import com.example.roleplay.domain.Persona;
import com.example.roleplay.domain.SessionMemory;
import com.example.roleplay.domain.Skill;
import com.example.roleplay.dto.BatchSessionCreateRequest;
import com.example.roleplay.dto.BatchSessionCreateResponse;
import com.example.roleplay.dto.SessionCreateRequest;
import com.example.roleplay.dto.SessionCreateResponse;
import com.example.roleplay.exception.BusinessException;
import com.example.roleplay.service.PersonaService;
import com.example.roleplay.service.SessionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 会话管理服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SessionServiceImpl implements SessionService {

    private final PersonaService personaService;
    private final RoleplayProperties properties;
    
    // 内存存储会话信息（生产环境建议使用Redis等持久化存储）
    private final Map<String, SessionMemory> sessionStore = new ConcurrentHashMap<>();

    @Override
    public SessionCreateResponse createSession(SessionCreateRequest request) {
        // 验证角色是否存在
        var persona = personaService.getPersonaById(request.getPersonaId());
        if (persona == null) {
            throw new BusinessException("角色不存在: " + request.getPersonaId());
        }

        // 检查会话数量限制
        if (sessionStore.size() >= properties.getSession().getMaxConcurrentSessions()) {
            throw new BusinessException("会话数量已达上限，请稍后重试");
        }

        // 生成会话ID
        String sessionId = UUID.randomUUID().toString();

        // 创建会话记忆
        SessionMemory sessionMemory = SessionMemory.builder()
                .sessionId(sessionId)
                .personaId(request.getPersonaId())
                .userId(request.getUserId())
                .createdAt(LocalDateTime.now())
                .lastActiveAt(LocalDateTime.now())
                .status(SessionMemory.SessionStatus.ACTIVE)
                .build();

        // 如果提供了用户偏好，初始化用户画像
        if (request.getPreferredLanguage() != null) {
            SessionMemory.UserProfile userProfile = SessionMemory.UserProfile.builder()
                    .preferredLanguage(request.getPreferredLanguage())
                    .build();
            sessionMemory.setUserProfile(userProfile);
        }

        // 存储会话
        sessionStore.put(sessionId, sessionMemory);

        log.info("创建新会话: {}, 角色: {}, 用户: {}", sessionId, request.getPersonaId(), request.getUserId());

        // 构建WebSocket URL
        String websocketUrl = String.format("/ws/chat/%s", sessionId);

        return SessionCreateResponse.builder()
                .sessionId(sessionId)
                .personaId(request.getPersonaId())
                .status("ACTIVE")
                .websocketUrl(websocketUrl)
                .build();
    }

    @Override
    public BatchSessionCreateResponse createBatchSessions(BatchSessionCreateRequest request) {
        // 获取三个主要角色
        List<String> mainPersonaIds = List.of("SG", "SW", "DF"); // 苏格拉底、孙悟空、达芬奇
        
        List<BatchSessionCreateResponse.SessionInfo> sessions = mainPersonaIds.stream()
                .map(personaId -> {
                    // 验证角色是否存在
                    Persona persona = personaService.getPersonaById(personaId);
                    if (persona == null) {
                        throw new BusinessException("角色不存在: " + personaId);
                    }

                    // 生成会话ID
                    String sessionId = UUID.randomUUID().toString();

                    // 创建会话记忆
                    SessionMemory sessionMemory = SessionMemory.builder()
                            .sessionId(sessionId)
                            .personaId(personaId)
                            .userId(request.getUserId())
                            .createdAt(LocalDateTime.now())
                            .lastActiveAt(LocalDateTime.now())
                            .status(SessionMemory.SessionStatus.ACTIVE)
                            .build();

                    // 如果提供了用户偏好，初始化用户画像
                    if (request.getPreferredLanguage() != null) {
                        SessionMemory.UserProfile userProfile = SessionMemory.UserProfile.builder()
                                .preferredLanguage(request.getPreferredLanguage())
                                .build();
                        sessionMemory.setUserProfile(userProfile);
                    }

                    // 存储会话
                    sessionStore.put(sessionId, sessionMemory);

                    log.info("创建新会话: {}, 角色: {}, 用户: {}", sessionId, personaId, request.getUserId());

                    // 构建 WebSocket URL
                    String websocketUrl = String.format("/ws/chat/%s", sessionId);
                    
                    // 获取音色名称
                    String voiceName = persona.getStyle() != null ? persona.getStyle().getVoiceName() : "tongtong";

                    return BatchSessionCreateResponse.SessionInfo.builder()
                            .sessionId(sessionId)
                            .personaId(personaId)
                            .personaName(persona.getName())
                            .personaInitials(personaId) // 直接使用ID作为缩写
                            .websocketUrl(websocketUrl)
                            .status("ACTIVE")
                            .voiceName(voiceName)
                            .build();
                })
                .collect(Collectors.toList());

        return BatchSessionCreateResponse.builder()
                .sessions(sessions)
                .build();
    }

    @Override
    public SessionMemory getSessionMemory(String sessionId) {
        SessionMemory memory = sessionStore.get(sessionId);
        if (memory != null && memory.getStatus() == SessionMemory.SessionStatus.ACTIVE) {
            return memory;
        }
        return null;
    }

    @Override
    public void updateSessionMemory(String sessionId, String userMessage, String assistantMessage,
                                  SessionMemory.MessageType messageType, List<Skill> skillsUsed) {
        SessionMemory memory = sessionStore.get(sessionId);
        if (memory != null) {
            memory.addConversationTurn(userMessage, assistantMessage, messageType, skillsUsed);
            
            // 更新用户画像（提取关键信息）
            updateUserProfile(memory, userMessage);
            
            log.debug("更新会话记忆: {}, 轮次: {}", sessionId, memory.getConversationHistory().size());
        }
    }

    @Override
    public void endSession(String sessionId) {
        SessionMemory memory = sessionStore.get(sessionId);
        if (memory != null) {
            memory.setStatus(SessionMemory.SessionStatus.ENDED);
            log.info("结束会话: {}", sessionId);
        }
    }

    @Override
    @Scheduled(fixedRate = 300000) // 每5分钟清理一次
    public void cleanupExpiredSessions() {
        int timeoutMinutes = properties.getSession().getTimeoutMinutes();
        int expiredCount = 0;

        for (Map.Entry<String, SessionMemory> entry : sessionStore.entrySet()) {
            SessionMemory memory = entry.getValue();
            if (memory.isExpired(timeoutMinutes)) {
                memory.setStatus(SessionMemory.SessionStatus.EXPIRED);
                sessionStore.remove(entry.getKey());
                expiredCount++;
            }
        }

        if (expiredCount > 0) {
            log.info("清理过期会话: {} 个", expiredCount);
        }
    }

    @Override
    public boolean isSessionValid(String sessionId) {
        SessionMemory memory = sessionStore.get(sessionId);
        return memory != null && 
               memory.getStatus() == SessionMemory.SessionStatus.ACTIVE &&
               !memory.isExpired(properties.getSession().getTimeoutMinutes());
    }

    @Override
    public void updateSessionActivity(String sessionId) {
        SessionMemory memory = sessionStore.get(sessionId);
        if (memory != null) {
            memory.updateLastActiveTime();
        }
    }

    @Override
    public void clearSessionMemory(String sessionId) {
        SessionMemory memory = sessionStore.get(sessionId);
        if (memory != null) {
            // 清空对话历史但保留会话基本信息
            memory.getConversationHistory().clear();
            memory.updateLastActiveTime();
            log.info("清空会话记忆: {}", sessionId);
        }
    }

    /**
     * 更新用户画像信息
     */
    private void updateUserProfile(SessionMemory memory, String userMessage) {
        if (memory.getUserProfile() == null) {
            memory.setUserProfile(SessionMemory.UserProfile.builder().build());
        }

        SessionMemory.UserProfile profile = memory.getUserProfile();

        // 简单的关键信息提取（实际应用中可以使用NLP技术）
        if (userMessage.contains("我叫") || userMessage.contains("我是")) {
            // 提取姓名信息
            // 这里只是简单示例，实际应用需要更复杂的NLP处理
        }

        if (userMessage.contains("喜欢") || userMessage.contains("爱好")) {
            // 提取兴趣信息
            if (profile.getInterests() == null) {
                profile.setInterests(List.of());
            }
        }

        // 可以添加更多的用户画像更新逻辑
    }
}